
  {DECLARE.PA2}

  {****************************************************}
  {                     Constants                      }
  {****************************************************}

  {$IFDEF NormalVersion}

CONST                             {CONST for Normal Version}
  {Locations: each noun and creature has a location at any given}
  {time, stored as an integer. This should correspond to the}
  {range from (Nowhere..last_creature), broken down as follows:}
  {       0:  noun has been destroyed or}
  {           noun never existed - undefined}
  {       1:  noun is being carried by player}
  {           (and moves with him/her/it)}
  {    1000:  noun is being worn by player}
  {           (and moves with him/her/it)}
  {  2..199:  noun is located in a room within the}
  {           adventure game map.}
  {200..299:  noun is located inside another noun}
  {300..399:  noun is being carried by a creature}

  {Creatures may only be located in the range  0..199, since}
  {they cannot be inside a noun. They also cannot be carried}
  {by the player, so the value 1 is also invalid.}
  {The player's location must be a room number (2..199)}
  Player = 1;
  Wearing = 1000;
  First_Room = 2;
  Last_Room = 199;
  First_noun = 200;
  Last_noun = 299;
  First_creature = 300;
  Last_Creature = 399;
  First_Message = 1;
  Last_Message = 250;
  Num_Verbs = 105;
  {number of verbs understood by program}
  Num_Dirs = 13;                  {13 directions: 10 dirs, plus}
  {'ENTER' and 'EXIT' and 'special' direction}
  MaxSizeCommand = 30;            {max. number of data items in SpecialCMD}
  MaxCommand = 400;               {max. number of SpecialCMDs}
  MaxCounter = 25;                {max. number of counters}
  MaxVariable = 25;               {max. number of variables}
  MaxQuestion = 25;               {max. number of questions and answers}
  MaxFlag = 255;                  {max. number of flags}
  MaxDupsInRoom = 5;              {max. number of duplicate nouns with same name in room}

  {$ELSE}

CONST {CONST for "BIG" Version}
  {Locations: each noun and creature has a location at any given}
  {time, stored as an integer. This should correspond to the}
  {range from (Nowhere..last_creature), broken down as follows:}
  {       0:  noun has been destroyed or}
  {           noun never existed - undefined}
  {       1:  noun is being carried by player}
  {           (and moves with him/her/it)}
  {    1000:  noun is being worn by player}
  {           (and moves with him/her/it)}
  {  2..299:  noun is located in a room within the}
  {           adventure game map.}
  {300..499:  noun is located inside another noun}
  {500..699:  noun is being carried by a creature}

  {Creatures may only be located in the range  0..299, since}
  {they cannot be inside a noun. They also cannot be carried}
  {by the player, so the value 1 is also invalid.}
  {The player's location must be a room number (2..299)}
  Player = 1;
  Wearing = 1000;
  First_Room = 2;
  Last_Room = 299;
  First_noun = 300;
  Last_noun = 499;
  First_creature = 500;
  Last_Creature = 699;
  First_Message = 1;
  Last_Message = 600;
  Num_Verbs = 105;
  {number of verbs understood by program}
  Num_Dirs = 13;                  {13 directions: 10 dirs, plus}
  {'ENTER' and 'EXIT' and 'special' direction}
  MaxSizeCommand = 30;            {max. number of data items in SpecialCMD}
  MaxCommand = 900;               {max. number of SpecialCMDs}
  MaxCounter = 50;                {max. number of counters}
  MaxVariable = 50;               {max. number of variables}
  MaxQuestion = 25;               {max. number of questions and answers}
  MaxFlag = 255;                  {max. number of flags}
  MaxDupsInRoom = 5;              {max. number of duplicate nouns with same name in room}
{$ENDIF}

  {****************************************************}
  {                     Types                          }
  {****************************************************}

TYPE
  String30 = String[30];
  String255 = String[255];
  CreatureType = (Thing {default creature/animal/beast} ,
                  Woman {changes pronouns to "SHE" and "HER"} ,
                  Man {changes pronouns to "HE" and "HIM"} );
  SingularOrPlural = (Singular, Plural);
  {used to select "IS" or "ARE" and "IT" or "THEM" for nouns}
  Direction = (NORTH, SOUTH, EAST, WEST, northeast, northwest, southeast,
               southwest, up, down, enter, Exit);
  {possible directions leading from each room}
  s = String[80];                 {sentences, lines of text}
  names = String[22];             {room, noun names}
  words = names;                  {words in player input}
  descr_files = FILE OF s;

  descr = RECORD
            start : Integer;      {position in descr_file}
            len : Integer;        {number of lines}
          END;

  Dups = RECORD
           num : Integer;         {number of duplicate noun/creature in room}
           adj : words;           {adjective}
           name : words;          {proper name -- NOT synonym}
         END;

  {**************************************************}
  {            Room Data Structure                   }
  {**************************************************}

  RoomPointer = ^rooms;

  rooms = RECORD
            name : String30;
            Replaced_Word : words; {In this room only -- Replace this verb}
            Replacing_Words : s;  {with these verbs}
            Path : ARRAY[Direction] OF Integer; {exits from room -- changed by DRM}
            special : Integer;
            has_seen : Boolean;   {player has seen room}
            key : Integer;        {noun that activates special}
            locked_door : Boolean;
            nouns_inside : Integer; {count of nouns in this room}
            points : Integer;     {reward for getting here}
            light : Integer;
            {what noun lights this room?}
            {0 means no light needed 1 means any light}
            game_end : Boolean;
            game_win : Boolean;
            player_dead : Boolean; {does player die when entering room?}
          END;                    {record}

  roomlists = ARRAY[First_Room..Last_Room] OF RoomPointer;

  {******************************************************}
  {              Nouns data structure                    }
  {******************************************************}

  NounPointer = ^nouns;

  nouns = RECORD
            name : names;
            short : s;            {short one-line description}
            adj : names;          {adjective - 'NO_ADJ' if none}
            SingOrPlur : SingularOrPlural; {used to select "IS" or "ARE"}
            position : names;     {i.e., 'behind the door'-- Added by DRM}
            SomethingPositionedNearThisNoun : Boolean;
            {i.e.,something is 'behind' this noun'}
            ThisNounPositionedNearNounNumber : Integer;
            {i.e.,number of noun this noun is 'behind'}
            Has_Synonyms : Boolean; {Are there Synonyms for this noun's name}
            synonyms : s;         {List of Synonyms for this noun -- if any}
            location : Integer;   {where is it? 1=player}
            weight : Integer;     {how heavy?}
            size : Integer;       {how bulky?}
            key : Integer;        {item # that unlocks it}
            pushable : Boolean;   {'specials' and 'PUSH_DESCR'}
            pullable : Boolean;   {'specials' and 'PULL_DESCR'}
            turnable : Boolean;   {'specials' and 'TURN_DESCR'}
            playable : Boolean;   {'specials' and 'PLAY_DESCR'}
            readable : Boolean;   {if true, there should be}
            {TEXT to match in the data file}
            on : Boolean;         {if not on, then off}
            closable : Boolean;   {can player open/close it?}
            open : Boolean;       {can things be put in it?}
            lockable : Boolean;   {can it be locked and unlocked?}
            locked : Boolean;     {if so, is it locked now?}
            edible : Boolean;     {can it be eaten?}
            wearable : Boolean;   {can it be worn?}
            drinkable : Boolean;  {can it be drunk?}
            poisonous : Boolean;  {if it's eaten or drunk}
            movable : Boolean;    {can it be lifted at all?}
            is_light : Boolean;   {does it work as a light?}
            can_shoot : Boolean;  {can it shoot ?}
            num_shots : Integer;  {number of bullets}
            points : Integer;     {what's it worth?}
            nouns_inside : Integer; {count of other nouns inside this noun}
            game_win : Boolean;   {does player win when}
            {s/he gets this noun?}
          END;                    {record}

  nounlists = ARRAY[First_noun..Last_noun] OF NounPointer;

  {***************************************************}
  {            Creatures data structure               }
  {***************************************************}

  CreaturePointer = ^creatures;   {to save DATA segment space}

  creatures = RECORD
                name : names;
                short : s;        {short one-line description}
                adj : names;      {adjective - 'NO_ADJ' if none}
                Has_Synonyms : Boolean; {Are there Synonyms for this creature's name}
                synonyms : s;     {List of Synonyms for this creature -- if any}
                groupmember : Boolean; {is it a member of the group?}
                location : Integer;
                weapon : Integer; {item # that kills it}
                hostile : Boolean; {is s/he/it hostile?}
                points : Integer; {what's it worth?}
                nouns_inside : Integer; {count of nouns creature is carrying}
                counter : Integer; {how many times has the}
                {player been nasty to it?}
                threshhold : Integer; {how many will it take?}
                timethresh : Integer; {how long before it attacks?}
                timecounter : Integer; {how many turns has}
                {the player been here?}
                gender : CreatureType; {Thing(default), Woman, Man}
              END;                {record}

  creaturelists = ARRAY[First_creature..Last_Creature] OF CreaturePointer;

  {***********************************************}
  {        Custom Command Data Structure          }
  {***********************************************}

  CommandPointer = ^Command;

  Command = RECORD
              VerbNum : Integer;  {verb number}
              VerbCMD : words;    {verb}
              NounCMD : words;    {noun}
              ObjectCMD : words;  {object}
              Data : ARRAY[1..MaxSizeCommand] OF Integer;
            END;                  {of record}

  CommandList = ARRAY[1..MaxCommand] OF CommandPointer;

  {***********************************************}
  {   S P E C I A L  C O M M A N D  T O K E N S   }
  {***********************************************}

  {*******  CONDITION TOKENS ********}
  Token = (
    AtLocation,                   {Player is located at room loc#}
    AtLocationGT,                 {In room greater than loc#}
    AtLocationLT,                 {In room less than loc#}
    FirstVisitToRoom,             {Player is in current room for first time}
    NewLife,                      {Player is just starting game or has just been resurrected}
    IsCarryingSomething,          {Player is carrying something}
    IsCarryingNothing,            {Player is carrying nothing}
    IsWearingSomething,           {Player is wearing something}
    IsCarryingTreasure,           {Player is carrying at least one treasure worth >= PTS}
    IsWearingNothing,             {Player is wearing nothing}
    LoadWeightEquals,             {Load weighs equals num#}
    LoadWeightGT,                 {Load weighs more than num#}
    LoadWeightLT,                 {Load weighs less than num#}
    Present,                      {ITEM is in room, carried or worn}
    IsWearing,                    {ITEM is being worn}
    IsCarrying,                   {ITEM is being carried}
    IsNowhere,                    {ITEM is located NOWHERE (room 0)}
    IsSomewhere,                  {ITEM is located somewhere}
    InRoom,                       {ITEM is located in current room}
    IsLocated,                    {ITEM# is located in room loc#}
    Together,                     {ITEM# and ITEM# are in same room}
    IsON,                         {ITEM is ON}
    IsOFF,                        {ITEM is OFF}
    IsGroupMember,                {ITEM is member of the group}
    IsOpen,                       {ITEM is Open}
    IsClosed,                     {ITEM is Closed}
    IsLocked,                     {ITEM is Locked}
    IsUnLocked,                   {ITEM is UnLocked}
    IsEdible,                     {ITEM is Edible}
    IsDrinkable,                  {ITEM is Drinkable}
    IsPoisonous,                  {ITEM is Poisonous}
    IsMovable,                    {ITEM is Movable}
    NOUNPresent,                  {NOUN is in room, carried or worn}
    NOUNIsWearing,                {NOUN is being worn}
    NOUNIsCarrying,               {NOUN is being carried}
    NOUNIsNowhere,                {NOUN ITEM is located NOWHERE (room 0)}
    NOUNIsSomewhere,              {NOUN ITEM is located somewhere}
    NOUNInRoom,                   {NOUN ITEM is located in current room}
    NOUNIsLocated,                {NOUN ITEM is located in room loc#}
    NOUNIsON,                     {NOUN ITEM is ON}
    NOUNIsOFF,                    {NOUN ITEM is OFF}
    NOUNIsOpen,                   {NOUN ITEM is Open}
    NOUNIsClosed,                 {NOUN ITEM is Closed}
    NOUNIsLocked,                 {NOUN ITEM is Locked}
    NOUNIsUnLocked,               {NOUN ITEM is UnLocked}
    NOUNIsEdible,                 {NOUN ITEM is Edible}
    NOUNIsDrinkable,              {NOUN ITEM is Drinkable}
    NOUNIsPoisonous,              {NOUN ITEM is Poisonous}
    NOUNIsMovable,                {NOUN ITEM is Movable}
    NOUNpointsEquals,             {NOUN points equal num#}
    NOUNpointsGT,                 {NOUN points are greater than num#}
    NOUNpointsLT,                 {NOUN points are less than num#}
    NOUNweightEquals,             {NOUN weight equals num#}
    NOUNweightGT,                 {NOUN weight is greater than num#}
    NOUNweightLT,                 {NOUN weight is less than num#}
    LightPresent,                 {Room has necessary light}
    RoomNeedsLight,               {Room needs a light}
    FlagON,                       {Flag# is ON}
    FlagOFF,                      {Flag# is OFF}
    ScoreEquals,                  {current score is equal to num}
    ScoreGT,                      {score is greater than num}
    ScoreLT,                      {score is less than num}
    NumberEquals,                 {current input number is equal to num}
    NumberGT,                     {input number is greater than num}
    NumberLT,                     {input number is less than num}
    AnswerIsCorrect,              {last answer is correct}
    AnswerIsWrong,                {last answer is wrong}
    TurnsEquals,                  {current Turns is equal to num}
    TurnsGT,                      {Turns is greater than num}
    TurnsLT,                      {Turns is less than num}
    CounterEquals,                {Counter # is equal to num}
    CounterGT,                    {Counter # is greater than num}
    CounterLT,                    {Counter # is less than num}
    VariableEquals,               {Variable # is equal to num}
    VariableGT,                   {Variable # is greater than num}
    VariableLT,                   {Variable # is less than num}
    CompareVariables,             {TRUE if V1 < V2 }
    VariableChance,               {TRUE if V < Random(1..N)}
    NamePresent,                  {TRUE if Name being addressed is at location}
    NameIsNumber,                 {TRUE if Name being addressed is Noun or Creature Number num}
    NOUNIsNumber,                 {TRUE if NOUN is Number num}
    ObjectIsNumber,               {TRUE if Object is Number num}
    SomethingInside,              {TRUE if there is something inside of object num}
    Chance,                       {Odds are percent, i.e. 10 %}
    PromptForYES,                 {Prompts for Y or N -- Ok if Yes}
    PromptForNO,                  {Prompts for Y or N -- Ok if No}
    VerbIsDirection,              {Verb is movement or direction}
    NounIsCreature,               {TRUE if noun is a creature}
    ObjectIsCreature,             {TRUE if object is a creature}
    ObjectPresent,                {TRUE if object is present in room}
    LogicalNOT,                   {Logical NOT of current condition}
    LogicalOR,                    {Logical OR of conditions -- MUST be last condition}
    {in CMD file token in indicated as "OR"}

    {******* ACTIONS TOKENS *********}

    GoToRoom,                     {Send player to loc#}
    GoToRandomRoom,               {Randomly pick room >= num1 and <= num2 and move player}
    MakeVarRoomNum,               {Var# -- will make Var# equal current room number}
    MakeVarNounNum,               {Var# -- will make Var# equal current noun number}
    MakeVarObjectNum,             {Var# -- will make Var# equal object room number}
    GoToVariableRoom,             {Var# -- will send player to room number Var#}
    SendToVariableRoom,           {Item# Var# -- will send Item# to room number Var#}
    GetVariableIt,                {Var# -- will get Var# item for player}
    PrintVariableMessage,         {Var# -- will print message number Var#}
    GetIt,                        {ITEM# is now being carried}
    WearIt,                       {ITEM# is now being worn}
    DropIt,                       {Drops ITEM# into current room}
    RemoveIt,                     {Removes ITEM and drops into room}
    GetNOUN,                      {NOUN is now being carried}
    WearNOUN,                     {NOUN is now being worn}
    DropNOUN,                     {Drops NOUN into current room}
    RemoveNOUN,                   {Removes NOUN and drops into room}
    DropEverything,               {Drop all items being carried}
    RemoveEverything,             {Remove all items being worn}
    KillPlayer,                   {Makes player dead}
    PutInCurrentRoom,             {Put ITEM# in current room}
    SendToRoom,                   {Put ITEM# in room loc#}
    PutNOUNInCurrentRoom,         {Put NOUN in current room}
    SendNOUNToRoom,               {Put NOUN in room loc#}
    SendAllToRoom,                {Send all carried ITEMs to loc#}
    SendTreasuresToRoom,          {Send all carried ITEMs whose points > pts# to loc#}
    RelocateAll,                  {Move all items at loc1 to loc2}
    Destroy,                      {ITEM# is now NOWHERE (room 0)}
    DestroyNOUN,                  {NOUN is now NOWHERE (room 0)}
    SwapLocations,                {swap locations of ITEM1 & ITEM2}
    SendToItem,                   {Put ITEM1 in location of ITEM2}
    SendNOUNToItem,               {Put NOUN in location of ITEM}
    AddToGroup,                   {Add ITEM# to group}
    RemoveFromGroup,              {Remove ITEM# from group}
    MoveTheGroup,                 {Move group to room ITEM#}
    ReDirectTo,                   {Re-Direct command to different VERB-NOUN-OBJECT}
    RandomMessage,                {Select message between Num1 and Num2 and print it}
    ShowContents,                 {Display object inside of num -- if any}
    OpenIt,                       {ITEM# is now open}
    CloseIt,                      {ITEM# is now closed}
    LockIt,                       {ITEM# is now locked}
    UnlockIt,                     {ITEM# is now unlocked}
    OpenNOUN,                     {NOUN is now open}
    CloseNOUN,                    {NOUN is now closed}
    LockNOUN,                     {NOUN is now locked}
    UnlockNOUN,                   {NOUN is now unlocked}
    ShowScore,                    {Show current SCORE}
    PlusScore,                    {Add num to current SCORE}
    MinusScore,                   {Subtract num from current SCORE}
    ShowInventory,                {Show current INVENTORY}
    WaitForReturn,                {Prints 'Hit RETURN' message}
    TimePasses,                   {Show 'Time passes...' message}
    xDelay,                       {Delay for num seconds}
    CLEARSCREEN,                  {Clears screen}
    DescribeThing,                {Describe thing num (whatever)}
    LookAtRoom,                   {Cause a VERBOSE look at room}
    PrintMessage,                 {Prints message num}
    BlankLine,                    {Prints blank line}
    Tone,                         {makes a sound at H hertz for M milliseconds}
    GetNumberInput,               {Get number as input}
    AskQuestion,                  {ask question and get answer}
    ChangePassageway,             {opens or closes a passage between rooms}
    TurnFlagON,                   {Turn Flag# ON}
    TurnFlagOFF,                  {Turn Flag# OFF}
    ToggleFlag,                   {Toggle Flag#}
    TurnCounterON,                {Turn counter# ON -- sets to 1}
    TurnCounterOFF,               {Turn counter# OFF -- sets to 0}
    SetVariableTo,                {Set Variable var# to num#}
    AddToVariable,                {Add num# to Variable var#}
    SubtractFromVariable,         {Subtract num# from Variable #}
    AddVariables,                 {Add V2 to V1 and store answer in V1}
    SubtractVariables,            {Subtract V2 from V1 and store answer in V1}
    RandomVariable,               {Set Var# to Random number [1..Num]}
    NounToVariable,               {Convert Noun to Variable #}
    ObjectToVariable,             {Convert Object to Variable #}
    WinGame,                      {Player wins game at end of turn}
    EndGame,                      {game ends at end of turn}
    QuitThisCMD,                  {Quit evaluating this CMD}
    QuitAllCMDs,                  {Finished with all special CMDs}
    DoneWithTurn);                {All Done this turn -- get next turn's input next}
  {last token}

  {***********************************************}
  {        Verbs and Global synonym lists         }
  {***********************************************}

  verblists = ARRAY[0..Num_Verbs] OF words; {0 is for 'ANY'}
  Synlists = ARRAY[0..Num_Verbs] OF s; {whole line of several synonyms}

  {****************************************************}
  {                 Global Variables                   }
  {****************************************************}

VAR
  SpecialCMD : CommandList;       {stores pointers to custom commands}
  counter : ARRAY[0..MaxCounter] OF Integer;
  Variable : ARRAY[0..MaxVariable] OF Integer;
  Question, Answer : ARRAY[0..MaxQuestion] OF s;
  Flag : ARRAY[0..MaxFlag] OF Boolean;
  P : ARRAY[Token] OF Integer;
  DuplicatesInRoom : ARRAY[1..MaxDupsInRoom] OF Dups;
  Cap_Subject_IT, Subject_IT, Object_IT, Snarls, Screeches : ARRAY[CreatureType] OF words;
  IsOrAre, ItOrThem : ARRAY[SingularOrPlural] OF words;
  StartingIndex : ARRAY[0..Last_Creature] OF Integer; {used for index}
  EndingIndex : ARRAY[0..Last_Creature] OF Integer; {sequential searches}
  Skip_A_Line : Boolean;
  ScoreAdjustment, Treasure_Room, Maximum_Score, NumberInRoom : Integer;
  Room : roomlists;
  Current_room : Integer;         {what room is player "now" in}
  Starting_room : Integer;        {the room the player starts in}
  Current_Life : Integer;         {what life is player now playing}
  Num_turns : Integer;            {number of turns taken}
  Num_saves, num_restores : Integer; {# of times game saved/restored}
  N : nounlists;                  {array [first_noun..last_noun] of nouns}
  M : creaturelists;              {array [first_creature..last_creature] of creatures}
  V : verblists;                  {the array of verbs, used only to check input}
  SYN : Synlists;                 {verb synonyms -- whole line full of synonyms}
  Original_Verb, LastVerb : words; {verb (as entered) before any synonym substitition}
  Last_CMD, MaxRoom, MaxNoun, MaxCreature, MaxVerb : Integer;
  Any_Special_Cmds, CreatingFinalVersion, UsingFinalVersion : Boolean; {flag -- TRUE of appropriate}
  datafile : Text;
  descr_file : descr_files;
  Command_File_Name, Instruction_File_Name, Adventure_Name,
  data_file_name, message_file_name, title_file_name, descr_file_name : words;
  player_dead : Boolean;          {useful so player knows when s/he dies}
  game_won, game_end, QuestionStatus, DoingUpperCase,
  PreviousCompoundCommands, DoingCompoundCommands : Boolean;
  verbose : Boolean;              {does player want long descriptions when s/he}
  {first enters a room, or only when requested?}
  morecount : Integer;            {number of lines since last pause}
  NormalConOutPtr : Integer;
  {used to replicate the Ctrl PrtSc key in software}
  {for SCRIPT and UNSCRIPT commands}
  Items_Being_Carried : Integer;
  Items_Being_Worn : Integer;
  Resurrection_Room, Max_Lives : Integer;

  {Pointers to descriptions on disk}
  Room_Ptr : ARRAY[First_Room..Last_Room] OF descr;
  Special_Ptr : ARRAY[First_Room..Last_Room] OF descr;
  Help_Ptr : ARRAY[First_Room..Last_Room] OF descr;
  Noun_Ptr : ARRAY[First_noun..Last_noun] OF descr;
  Play_Ptr : ARRAY[First_noun..Last_noun] OF descr;
  Turn_Ptr : ARRAY[First_noun..Last_noun] OF descr;
  Push_Ptr : ARRAY[First_noun..Last_noun] OF descr;
  Pull_Ptr : ARRAY[First_noun..Last_noun] OF descr;
  Text_Ptr : ARRAY[First_noun..Last_noun] OF descr;
  Message_Ptr : ARRAY[First_Message..Last_Message] OF descr;
  Creature_Ptr : ARRAY[First_creature..Last_Creature] OF descr;
  Intro_Ptr : descr;
  LastPart : s;                   {used for player's input string}
  noun, object_word, noun_adj, object_adj, NameStr : words; {returned by parser}
  last_noun_used, last_adj_used : words;
  {used by parser to understand "IT" "THEM" "HIM" & "HER"}
  NounNumber, ObjectNumber, NameNum : Integer;
  {determined in parser}
  Duplicate : Boolean;
  Adjective : words;
  NumberOfErrors, TopRoom, TopNoun, TopCreature, TopMessage, MaxMessage : Integer;
  Word_Chars : SET OF Char;

TYPE
  TestType = (RoomTest, NounTest, CreatureTest, ThingTest, LocationTest, TokenTest,
              ZRoomTest, ZNounTest, MessageTest, CounterTest, VariableTest, QuestionTest, FlagTest);
